package com.zx.map.service.impl;

import com.zx.map.dao.CreditRepayLogDao;
import com.zx.map.dao.model.CreditRepayLog;
import com.zx.map.dao.model.CreditRepayLogExample;
import com.zx.map.service.BaseAcctInfoService;
import com.zx.map.service.CreditRepayLogService;
import com.zx.map.service.CustAcctLogService;
import com.zx.map.service.RemoteIntefaceVisitService;
import com.zx.map.service.model.*;
import com.zx.mobile.domain.CreditRepayLogQueryDomain;
import com.zx.mobile.service.proxy.CreditRepayCommonProxy;
import com.zx.platform.utils.PmpUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA. User: Administrator Date: 14-3-1 Time: 上午11:07 To
 * change this template use File | Settings | File Templates.
 */
@Component("creditRepayLogService")
public class CreditRepayLogServiceImpl implements CreditRepayLogService {
    /**
     * log
     */
    private static Logger log = Logger
            .getLogger(CreditRepayLogServiceImpl.class);

    @Autowired
    private CreditRepayLogDao dao;
    @Autowired
    private RemoteIntefaceVisitService remoteIntefaceVisitService;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private BaseAcctInfoService baseAcctInfoService;
    @Autowired
    private CustAcctLogService custAcctLogService;

    /**
     * 实时出款
     */
    public CreditRepayResponse dealCreditRepay(
            final CreditRepayLogModel creditRepayLogModel, final CreditRepayInfoModel creditOne) {
        CreditRepayResponse creditRepayResponse = (CreditRepayResponse) transactionTemplate
                .execute(new TransactionCallback<Object>() {
                    @Override
                    public Object doInTransaction(TransactionStatus arg0) {
                        CreditRepayResponse creditRepayResponse = new CreditRepayResponse();
                        BaseAcctInfoModel temp = baseAcctInfoService.getModelByKeyAndLineLock(creditOne.getMerchantId());
                        if (temp.getAvlBal() >= creditRepayLogModel.getTradeAmt()) {
                            // 0、增加信用还款记录
                            add(creditRepayLogModel);
                            // 1、扣减账户余额
                            temp = CreditRepayCommonProxy.transformSubBaseAcct(temp,
                                    creditRepayLogModel.getTradeAmt().toString());
                            baseAcctInfoService.update(temp);
                            CustAcctLogModel custModel = CreditRepayCommonProxy.transformCustAcct(temp, creditRepayLogModel);
                            custAcctLogService.add(custModel);
                            // 2.请求
                            try {//确保在任何情况下  均实现扣款  我方不短款
                                PayCmbResponseModel payCmbResponseModel = remoteIntefaceVisitService.outComeSingleByCmb(
                                        creditRepayLogModel, creditOne);
                                log.info("信用卡还款返回信息:" + ToStringBuilder.reflectionToString(payCmbResponseModel));
                                creditRepayResponse.setReturnCode(payCmbResponseModel.getReturnCode());
                                creditRepayResponse.setErrMsg(payCmbResponseModel.getErrMsg());
                                //更新原始交易
                                String tradeStatus = "0000".equals(payCmbResponseModel.getReturnCode()) ? "S" : "F";
                                creditRepayLogModel.setRepayStatus(tradeStatus);
                                creditRepayLogModel.setSettleStatus(tradeStatus);
                                creditRepayLogModel.setSettleOrdId(payCmbResponseModel.getCmbOrderId());
                                creditRepayLogModel.setSettleRemark(payCmbResponseModel.getErrMsg());
                                update(creditRepayLogModel);
                                // 0000 明确成功  9000 银行明确失败  9999 失败
                                if ("9000".equals(creditRepayResponse.getReturnCode())) {
                                    log.info("银行明确失败 需要资金退回");
                                    //资金回退  原始锁定记录
                                    temp = CreditRepayCommonProxy.transformAddBaseAcct(temp,
                                            creditRepayLogModel.getTradeAmt().toString());
                                    custModel = CreditRepayCommonProxy.transformReverseCustAcct(temp, creditRepayLogModel);
                                    custAcctLogService.add(custModel);
                                    baseAcctInfoService.update(temp);
                                }
                                return creditRepayResponse;
                            } catch (Exception e) {
                                log.error("信用卡还款出现问题",e);
                                creditRepayResponse.setReturnCode("9999");
                                creditRepayResponse.setErrMsg("信用卡还款出现问题");
                            }
                        } else {
                            creditRepayResponse.setReturnCode("9999");
                            creditRepayResponse.setErrMsg("还款金额超过可用余额");
                        }
                        return creditRepayResponse;
                    }
                });
        return creditRepayResponse;
    }

    /**
     * 分页查询
     *
     * @param pageSize
     * @param pageNum
     * @param creditRepayLogModel
     * @return
     * @throws DataAccessException
     */
    public Map getPageByDomain(int pageSize, int pageNum,
                               CreditRepayLogModel creditRepayLogModel) throws DataAccessException {
        Map<String, Object> map = new HashMap<String, Object>();
        CreditRepayLogExample example = new CreditRepayLogExample();
        CreditRepayLogExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(creditRepayLogModel.getMerchantId())) {
            criteria.andMerchantIdEqualTo(creditRepayLogModel.getMerchantId());
        }
        if (StringUtils.isNotBlank(creditRepayLogModel.getMerSysAccount())) {
            criteria.andMerSysAccountEqualTo(creditRepayLogModel
                    .getMerSysAccount());
        }

        int pageBegin = (pageNum - 1) * pageSize;
        List<CreditRepayLog> list = dao.getPageByExample(pageSize, pageBegin,
                example);
        ;
        List<CreditRepayLogModel> modelList = new ArrayList<CreditRepayLogModel>();
        for (CreditRepayLog o : list) {
            CreditRepayLogModel temp = new CreditRepayLogModel();
            BeanUtils.copyProperties(o, temp);
            modelList.add(temp);
        }
        int count = dao.countListByExample(example);
        map.put("count", count);
        map.put("list", modelList);
        return map;
    }

    /**
     * 订单查询条件获取交易信息
     *
     * @param creditRepayLogModel
     * @return
     * @throws org.springframework.dao.DataAccessException
     */
    public List<CreditRepayLogModel> getListByModel(
            CreditRepayLogModel creditRepayLogModel) throws DataAccessException {
        CreditRepayLogExample example = new CreditRepayLogExample();
        CreditRepayLogExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(creditRepayLogModel.getMerchantId())) {
            criteria.andMerchantIdEqualTo(creditRepayLogModel.getMerchantId());
        }
        example.setOrderByClause("CREATE_DATE desc");
        List<CreditRepayLog> list = dao.getListByExample(example);
        List<CreditRepayLogModel> modelList = new ArrayList<CreditRepayLogModel>();
        for (CreditRepayLog o : list) {
            CreditRepayLogModel temp = new CreditRepayLogModel();
            BeanUtils.copyProperties(o, temp);
            modelList.add(temp);
        }
        return modelList;
    }

    /**
     * 新增
     */
    public String add(CreditRepayLogModel model) throws DataAccessException {
        CreditRepayLog temp = new CreditRepayLog();
        BeanUtils.copyProperties(model, temp);
        String key = dao.add(temp);
        return key;
    }

    /**
     * 修改
     */
    public String update(CreditRepayLogModel model) throws DataAccessException {
        CreditRepayLog temp = new CreditRepayLog();
        BeanUtils.copyProperties(model, temp);
        return dao.update(temp);
    }

    /**
     * 删除
     */
    public void delete(CreditRepayLogModel model) throws DataAccessException {
        CreditRepayLog temp = new CreditRepayLog();
        BeanUtils.copyProperties(model, temp);
        dao.delete(temp);
    }

    /**
     * 根据筛选的记录 更新某个字段
     */
    public void updateCreditRepayBySelect(
            CreditRepayLogModel creditRepayLogModel,
            CreditRepayLogModel modelSelected) {
        CreditRepayLogExample example = new CreditRepayLogExample();
        CreditRepayLogExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(modelSelected.getMerchantId())) {
            criteria.andMerchantIdEqualTo(modelSelected.getMerchantId());
        }
        if (StringUtils.isNotBlank(modelSelected.getSettleStatus())) {
            criteria.andSettleStatusEqualTo(modelSelected.getSettleStatus());
        }
        CreditRepayLog temp = new CreditRepayLog();
        BeanUtils.copyProperties(creditRepayLogModel, temp);
        dao.updateByExample(temp, example);
    }

    /**
     * 分页查询
     *
     * @param pageSize
     * @param pageNum
     * @return
     * @throws DataAccessException
     */
    public Map getPageByDomain(int pageSize, int pageNum, CreditRepayLogQueryDomain domain)
            throws DataAccessException {
        Map<String, Object> map = new HashMap<String, Object>();
        CreditRepayLogExample example = new CreditRepayLogExample();
        CreditRepayLogExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(domain.getMerSysAccount())) {
            criteria.andMerSysAccountEqualTo(domain.getMerSysAccount());
        }
        if (StringUtils.isNotBlank(domain.getBeginDate())) {
            criteria.andCreateDateBetween(PmpUtils.strToDate(
                    domain.getBeginDate(), "yyyy-MM-dd"), PmpUtils
                    .addDate(PmpUtils.strToDate(domain.getEndDate(),
                            "yyyy-MM-dd"), 1));
        }
        int pageBegin = (pageNum - 1) * pageSize;
        List<CreditRepayLog> list = dao.getPageByExample(pageSize, pageBegin, example);
        ;
        List<CreditRepayLogModel> modelList = new ArrayList<CreditRepayLogModel>();
        for (CreditRepayLog o : list) {
            CreditRepayLogModel temp = new CreditRepayLogModel();
            BeanUtils.copyProperties(o, temp);
            modelList.add(temp);
        }
        int count = dao.countListByExample(example);
        map.put("count", count);
        map.put("list", modelList);
        return map;
    }

    public List<CreditRepayLogModel> getListByDomain(
            CreditRepayLogQueryDomain domain) throws DataAccessException {
        CreditRepayLogExample example = new CreditRepayLogExample();
        CreditRepayLogExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(domain.getMerSysAccount())) {
            criteria.andMerSysAccountEqualTo(domain.getMerSysAccount());
        }
        if (StringUtils.isNotBlank(domain.getBeginDate())) {
            criteria.andCreateDateBetween(PmpUtils.strToDate(
                    domain.getBeginDate(), "yyyy-MM-dd"), PmpUtils
                    .addDate(PmpUtils.strToDate(domain.getEndDate(),
                            "yyyy-MM-dd"), 1));
        }
        List<CreditRepayLog> list = dao.getListByExample(example);
        List<CreditRepayLogModel> modelList = new ArrayList<CreditRepayLogModel>();
        for (CreditRepayLog o : list) {
            CreditRepayLogModel temp = new CreditRepayLogModel();
            BeanUtils.copyProperties(o, temp);
            modelList.add(temp);
        }
        return modelList;
    }
}
